package com.ll.domain.jj.base.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiUserGetRequest;
import com.dingtalk.api.response.OapiUserGetResponse;
import com.ll.app.api.jj.*;
import com.ll.app.api.jj.enums.JJProjectStatusEnum;
import com.ll.app.api.jj.enums.JJRoleEnum;
import com.ll.base.dto.PageResultDTO;
import com.ll.base.enums.FinishStatusEnum;
import com.ll.base.util.ListUtil;
import com.ll.base.util.ScalarUtil;
import com.ll.dal.mapper.JJClassMapper;
import com.ll.dal.mapper.JJProjectMapper;
import com.ll.dal.po.JJClassPO;
import com.ll.dal.po.JJProjectPO;
import com.ll.domain.dingtalk.base.DingTalkUserBaseService;
import com.ll.domain.dingtalk.constant.URLConstant;
import com.ll.domain.dingtalk.utils.AccessTokenUtil;
import com.ll.domain.jj.base.JJProjectBaseService;
import com.ll.domain.jj.convert.JJProjectConvert;
import com.taobao.api.ApiException;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 班级服务
 *
 * @author WuHen
 * @date 2021/10/16 17:54
 **/
@Service
@RequiredArgsConstructor
public class JJProjectBaseServiceImpl extends ServiceImpl<JJProjectMapper, JJProjectPO> implements JJProjectBaseService {

    private final JJProjectMapper jjProjectMapper;
    private final JJClassMapper jjClassMapper;
    private final DingTalkUserBaseService dingTalkUserBaseService;

    @Override
    public PageResultDTO<JJProjectDTO> page(PageJJProjectReqDTO req) {
        req.initPage();
        JJRoleEnum userRole = this.getUserRole(req.getCDingUid());
        String uid = req.getCDingUid();
        if(userRole !=  JJRoleEnum.老师){
            uid = null;
        }
        JJProjectStatusEnum status = JJProjectStatusEnum.buildByRole(userRole);
        FinishStatusEnum finishStatus = req.getFinishStatus() == null ? FinishStatusEnum.进行中 : req.getFinishStatus();

        IPage<JJProjectPO> iPage = new Page<JJProjectPO>(req.getPageNo(), req.getPageSize());
        iPage = jjProjectMapper.selectPage(iPage, new LambdaQueryWrapper<JJProjectPO>()
                .eq(ScalarUtil.isNotEmpty(uid) , JJProjectPO::getCDingUid, req.getCDingUid())
                .eq(status != null , JJProjectPO::getStatus, status)
                .eq(ScalarUtil.isEmpty(uid), JJProjectPO::getFinishStatus, finishStatus)
                .orderByDesc(JJProjectPO::getCtime)
        );

        List<JJProjectDTO> jjProjectDTOS = ListUtil.toList(iPage.getRecords(), JJProjectConvert::PO2DTO);
        jjProjectDTOS.forEach(r->{
            JJClassPO jjClassPO = jjClassMapper.selectById(r.getClassId());
            r.setClassName(jjClassPO.getClassName());

            r.setCUserName(r.getRecordList().get(0).getName());

            r.setIsHandler(userRole != JJRoleEnum.老师);

        });
        return new PageResultDTO<JJProjectDTO>(jjProjectDTOS, iPage.getTotal(), req);
    }

    @Override
    public boolean add(AddJJProjectDTO dto) {
        Date date = new Date();
        JJProjectPO po = new JJProjectPO();
        BeanUtils.copyProperties(dto, po);
        po.setCtime(date);
        po.setStatus(JJProjectStatusEnum.待审批);
        po.setFinishStatus(FinishStatusEnum.进行中);
        po.setRecord(this.buildInitRecord(dto.getCUserName(),
                "发起申请",
                        dto.getCDingUid(),
                true));
        return jjProjectMapper.insert(po) > 0;
    }

    @Override
    public boolean updateStatus(UpdateJJProjectStatusDTO dto) {
        JJProjectPO jjProjectPO = jjProjectMapper.selectById(dto.getId());

        if(JJProjectStatusEnum.待审批 == jjProjectPO.getStatus() && !dto.getStatus()){
            jjProjectPO.setFinishStatus(FinishStatusEnum.失败);
        }else if(JJProjectStatusEnum.待结案 == jjProjectPO.getStatus() && dto.getStatus()){
            jjProjectPO.setFinishStatus(FinishStatusEnum.成功);
        }else{
            if(dto.getStatus()){
                jjProjectPO.setStatus(jjProjectPO.getStatus().nextStatus());
            }else{
                jjProjectPO.setStatus(jjProjectPO.getStatus().lastStatus());
            }
        }
        List<JJProjectRecordDTO> recordDTOS = JSONObject.parseArray(jjProjectPO.getRecord(), JJProjectRecordDTO.class);
        JJProjectRecordDTO jjProjectRecordDTO = this.buildRecord(dto.getCUserName(), dto.getRemark(), dto.getCDingUid(), dto.getStatus());
        recordDTOS.add(jjProjectRecordDTO);
        jjProjectPO.setRecord(JSONObject.toJSONString(recordDTOS));
        return jjProjectMapper.updateById(jjProjectPO) > 0;
    }

    private String buildInitRecord(String name, String remark, String duid, Boolean status){
        List<JJProjectRecordDTO> result = new ArrayList<>();
        result.add(this.buildRecord(name,remark,duid,status));
        return JSONObject.toJSONString(result);
    }

    private JJProjectRecordDTO buildRecord(String name, String duid, Boolean status){
        return this.buildRecord(name,null,duid,status);
    }
    private JJProjectRecordDTO buildRecord(String name, String remark, String duid, Boolean status){
        if(ScalarUtil.isEmpty(remark)){
            remark = status? "审批通过" : "审批拒绝";
        }
        return JJProjectRecordDTO
                .builder()
                .name(name)
                .cDingUid(duid)
                .ctime(new Date())
                .remark(remark)
                .status(status)
                .build();
    }

    private JJRoleEnum getUserRole(String dUserId){
        DingTalkClient client = new DefaultDingTalkClient(URLConstant.URL_USER_GET);
        OapiUserGetRequest request = new OapiUserGetRequest();
        request.setUserid(dUserId);
        request.setHttpMethod("GET");
        OapiUserGetResponse response = null;
        try {
            response = client.execute(request, AccessTokenUtil.getJJToken());
        } catch (ApiException e) {
            e.printStackTrace();
            return JJRoleEnum.老师;
        }

        List<JJRoleEnum> jjRoleEnums = ListUtil.fitlerAndToList(response.getRoles()
                , r -> JJRoleEnum.checkRoleName(r.getName()), k -> JJRoleEnum.valueOf(k.getName()));
        return JJRoleEnum.getMaxRole(jjRoleEnums);
    }
}
